


#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;

class Solution
{
public:
    vector<int> subSort1(vector<int>& a)
    {
        if (a.empty() || 1 == a.size())
            return { -1, -1 };

        vector<int> v(a.begin(), a.end());
        sort(v.begin(), v.end());
        int lf = -1, rg = -1;

        int flag1 = 1, flag2 = 1;
        for (int beg = 0, end = a.size() - 1; beg < a.size() && end >= 0; ++beg, --end)
        {
            if (flag1 && a[beg] != v[beg])
            {
                lf = beg;
                flag1 = 0;
            }
            if (flag2 && a[end] != v[end])
            {
                rg = end;
                flag2 = 0;
            }
            if (lf > -1 && rg > -1)
                break;
        }

        return { lf, rg };
    }

    vector<int> subSort2(vector<int>& a)
    {
        int sz = a.size();

        if (a.empty() || 1 == a.size())
            return { -1, -1 };

        int lf = -1, rg = -1;
        int maxi = INT_MIN, mini = INT_MAX;

        for (int beg = 0, end = sz - 1; beg < sz && end >= 0; ++beg, --end)
        {
            int cur1 = a[beg];
            int cur2 = a[end];

            if (cur1 >= maxi)
                maxi = cur1;
            else
                rg = beg;

            if (cur2 <= mini)
                mini = cur2;
            else
                lf = end;
        }

        return { lf, rg };
    }

    vector<string> topKFrequent1(vector<string>& words, int k)
    {
        map<string, int> Map;

        for (const auto& e : words)
        {
            ++Map[e];
        }

        vector<string> vs;
        vector<pair<string, int>> v(Map.begin(), Map.end());

        stable_sort(v.begin(), v.end(), comp());
        for (int i = 0; i < k; ++i)
        {
            vs.push_back(v[i].first);
        }

        return vs;
    }

    vector<string> topKFrequent2(vector<string>& words, int k)
    {
        map<string, int> Map;

        for (const auto& e : words)
        {
            ++Map[e];
        }

        vector<string> vs;
        vector<pair<string, int>> v(Map.begin(), Map.end());

        sort(v.begin(), v.end(), kvComp());
        for (int i = 0; i < k; ++i)
        {
            vs.push_back(v[i].first);
        }

        return vs;
    }

private:
    struct kvComp
    {
        bool operator()(const pair<string, int>& kv1, const pair<string, int>& kv2)
        {
            return  kv1.second > kv2.second || (kv1.second == kv2.second && kv1.first < kv2.first);
        }
    };

    struct comp
    {
        bool operator()(const pair<string, int>& p1, const pair<string, int>& p2)
        {
            return p1.second > p2.second;
        }
    };
};

struct kvComp
{
    bool operator()(const pair<string, int>& x, const pair<string, int>& y)
    {
        return x.second < y.second || (x.second == y.second && x.first < y.first);
    }
};

// err
int main()
{
    string s;
    map<string, int> cnt;

    getline(cin, s, '.');
    s += '.';

    int endblank = s.rfind(' ');
    int beg = 0, end = 0;
    while (end != s.size())
    {
        end = s.find(' ', beg);
        if (end != string::npos)
        {
            string tmp = string(s.begin() + beg, s.begin() + end);
            for (int i = 0; i < tmp.size(); ++i)
            {
                tmp[i] = tolower(tmp[i]);
            }

            ++cnt[tmp];
        }

        beg = end + 1;
    }

    priority_queue<pair<string, int>, vector<pair<string, int>>, kvComp> hp(cnt.begin(), cnt.end());

    while (!hp.empty())
    {
        cout << hp.top().first << ":" << hp.top().second << endl;
        hp.pop();
    }

    return 0;
}
